package com.sean.iphoneAppWorkspace;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import android.content.Context;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;

/**
 * 可移动子View面板，实现拖拉子View调整子View的位置
 * @author Sean
 *
 */
public class DragLayout extends ViewGroup {
	
	public static final String TAG = "DragLayout";
	
	private int mMoveTime = 500;
	
	protected DragItemView[] mChildViews;
	private int[][] mChildCoordinates;
	
	/** 子View的大小*/
	protected int mChildSize;
	
	private int mChildCount;
	
	public DragLayout(Context context, int childSize, int[][] childCoordinates) {
		super(context);
		this.mChildCoordinates = childCoordinates;
		this.mChildSize = childSize;
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		DragItemView child = null;
		
		if(mChildViews == null) {
			mChildCount = this.getChildCount();
			mChildViews = new DragItemView[mChildCount];
			for(int i = 0; i < mChildCount; i ++) {
				mChildViews[i] = (DragItemView)this.getChildAt(i);
			}
		}
		
		for(int i = 0; i < mChildCount; i ++) {
			 child = mChildViews[i];
			 int left = mChildCoordinates[i][0];
			 int top = mChildCoordinates[i][1];
			 child.layout(left, top, left + mChildSize, top + mChildSize);
		}
		Log.i(TAG, "onLayout");
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		final int childCount = getChildCount();
		View child = null;
		int sizeSpec = MeasureSpec.makeMeasureSpec(mChildSize, MeasureSpec.EXACTLY);
		for(int i = 0; i < childCount; i++) {
			child = getChildAt(i);
			child.measure(sizeSpec, sizeSpec);
		}
	}
	
	/**
	 * 将当前某个子View移到到指定位置
	 * @param itemView 要移动的子View
	 * @param moveToPos 要移至的位置
	 */
	public void moveTo(DragItemView itemView, int moveToPos) {
		int srcPos = itemView.getData().getPosition();
		if(moveToPos == srcPos) {
			return;
		}
		Log.i(TAG, "Move from " + srcPos + " to " + moveToPos);
		DataVo data = null;
		List<DragItemView> mMoveList = new ArrayList<DragItemView>();
		for(int i = 0; i < mChildCount; i ++) {
			data = mChildViews[i].getData();
			if(moveToPos > srcPos && i <= moveToPos && i > srcPos) {
				data.setPosition(data.getPosition() - 1);
				mMoveList.add(mChildViews[i]);
			} else if(moveToPos < srcPos && i >= moveToPos && i < srcPos) {
				data.setPosition(data.getPosition() + 1);
				mMoveList.add(mChildViews[i]);
			} else if(srcPos == i) {
				data.setPosition(moveToPos);
//				mMoveList.add(mChildViews[i]);
			}
		}
		
		AnimationListener listener = new AnimationListener() {
			@Override
			public void onAnimationStart(Animation animation) { }
			@Override
			public void onAnimationRepeat(Animation animation) { }
			@Override
			public void onAnimationEnd(Animation animation) {
				Arrays.sort(mChildViews);
				DragLayout.this.requestLayout();
				
				DataVo data = null;
				DragItemView child = null;
				for(int i = 0; i < mChildCount; i ++) {
					child = mChildViews[i];
					data = child.getData();
					Log.i(TAG, "i = " + i + "; title : " + data.getText() + "; position : " + data.getPosition());
				}
				Log.i(TAG, "--------------------------------");
			}
		};
		
		int count = mMoveList.size();
		for(int i = 0; i < count; i ++) {
			DragItemView item = mMoveList.get(i);
			int position = item.getData().getPosition();
			if(i < count - 1) {
				item.moveTo(mChildCoordinates[position][0], mChildCoordinates[position][1], mMoveTime, null);
			} else {
				item.moveTo(mChildCoordinates[position][0], mChildCoordinates[position][1], mMoveTime, listener);
			}
		}
	}
	
	/**
	 * 将VIEW插入到当前布局中，如果该View已经布满子View,则返回溢出的子View
	 * @param itemView 将要插入的View
	 * @param insertPos 插入的位置
	 * @return
	 */
	public DragItemView insertTo(DragItemView itemView, int insertPos) {
		itemView.getData().setPosition(insertPos);
		Log.i(TAG, "Insert to " + insertPos);
		
		DragItemView overflowView = null;

		DataVo data = null;
		List<DragItemView> mMoveList = new ArrayList<DragItemView>();
		for(int i = 0; i < mChildCount; i ++) {
			data = mChildViews[i].getData();
			if(i >= insertPos) {
				if(mChildCount == mChildCoordinates.length && i == mChildCount - 1) {
					this.removeView(mChildViews[i]);
					overflowView = mChildViews[i];
					continue;
				}
				data.setPosition(data.getPosition() + 1);
				mMoveList.add(mChildViews[i]);
			}
		}
		
		if(overflowView == null) {
			mChildCount ++;
			DragItemView[] childViews = new DragItemView[mChildCount];
			DragItemView child = null;
			for(int i = 0; i < mChildCount - 1; i ++) {
				childViews[i] = mChildViews[i];
			}
			childViews[mChildCount - 1] = itemView;
			mChildViews = childViews;
		} else {
			mChildViews[mChildCount - 1] = itemView;
		}
		
		AnimationListener listener = new AnimationListener() {
			@Override
			public void onAnimationStart(Animation animation) { }
			@Override
			public void onAnimationRepeat(Animation animation) { }
			@Override
			public void onAnimationEnd(Animation animation) {
				DragLayout.this.addView(mChildViews[mChildCount - 1]);
				Arrays.sort(mChildViews);
				DragLayout.this.requestLayout();
				
				DataVo data = null;
				DragItemView child = null;
				for(int i = 0; i < mChildCount; i ++) {
					child = mChildViews[i];
					data = child.getData();
					Log.i(TAG, "i = " + i + "; title : " + data.getText() + "; position : " + data.getPosition());
				}
				Log.i(TAG, "--------------------------------");
			}
		};
		
		int count = mMoveList.size();
		if(count == 0) {
			DragLayout.this.addView(mChildViews[mChildCount - 1]);
			Arrays.sort(mChildViews);
			DragLayout.this.requestLayout();
		}
		for(int i = 0; i < count; i ++) {
			DragItemView item = mMoveList.get(i);
			int position = item.getData().getPosition();
			if(i < count - 1) {
				item.moveTo(mChildCoordinates[position][0], mChildCoordinates[position][1], mMoveTime, null);
			} else {
				item.moveTo(mChildCoordinates[position][0], mChildCoordinates[position][1], mMoveTime, listener);
			}
		}
		
		return overflowView;
	}
	
	/**
	 * 删除指定位置的子View，并对该面板中所有子view进行重新排列
	 * @param position
	 */
	public void remove(int position) {
		this.removeView(mChildViews[position]);
		DragItemView[] childViews = new DragItemView[mChildCount - 1];
		DragItemView child = null;
		int n = 0;
		for(int i = 0; i < mChildCount; i ++) {
			if(position != i) {
				mChildViews[i].getData().setPosition(n);
				childViews[n++] = mChildViews[i];
			}
		}
		mChildCount --;
		mChildViews = childViews;
		this.requestLayout();
	}
	
	/**
	 * 将子View插入到当前面板中 
	 */
	public boolean add(DragItemView itemView) {
		//如果子View已经布满，插入失败
		if(mChildCount == mChildCoordinates.length) {
			return false;
		}
		
		this.addView(itemView);
		itemView.getData().setPosition(mChildCount);
		mChildCount ++;
		DragItemView[] childViews = new DragItemView[mChildCount];
		for(int i = 0; i < mChildCount - 1; i ++) {
			childViews[i] = mChildViews[i];
		}
		childViews[mChildCount - 1] = itemView;
		mChildViews = childViews;
		this.requestLayout();
		return true;
	}
	
//	@Override
//	public boolean onTouchEvent(MotionEvent ev) {
//		
//		Log.i(TAG, "onTouchEvent");
//        
//		//释放则结束拖动的效果
//		switch (ev.getAction()) {
//        case MotionEvent.ACTION_CANCEL:
//        case MotionEvent.ACTION_UP:
//        	Log.i(TAG, "onTouchEvent >> UP");
//        	return false;
//      	}
//		return super.onTouchEvent(ev);
//	}
	
}
